﻿namespace AdvancedTraining.Lesson02;

public class SetAll
{
    public class MyValue<TV>(TV v, long t)
    {
        public readonly long Time = t;
        public readonly TV Value = v;
    }

    public class MyHashMap<TK, TV> where TK : notnull
    {
        private readonly Dictionary<TK, MyValue<TV>> _map = new();
        private MyValue<TV> _setAll = new(default!, -1);
        private long _time;

        public void Put(TK key, TV value)
        {
            _map[key] = new MyValue<TV>(value, _time++);
        }

        public void SetAll(TV value)
        {
            _setAll = new MyValue<TV>(value, _time++);
        }

        public TV Get(TK key)
        {
            if (!_map.ContainsKey(key)) return default!;
            if (_map[key].Time > _setAll.Time)
                return _map[key].Value;
            return _setAll.Value;
        }
    }

    /// <summary>
    /// 测试SetAll算法
    /// </summary>
    public static void Run()
    {
        Console.WriteLine("SetAll算法测试开始...");

        // 测试用例1：基本功能测试
        var map1 = new MyHashMap<int, string>();
        map1.Put(1, "A");
        map1.Put(2, "B");
        map1.Put(3, "C");

        Console.WriteLine("测试1 - 基本操作:");
        Console.WriteLine($"Put(1,'A'), Put(2,'B'), Put(3,'C')");
        Console.WriteLine($"Get(1): {map1.Get(1)}");  // 期望: A
        Console.WriteLine($"Get(2): {map1.Get(2)}");  // 期望: B
        Console.WriteLine($"Get(3): {map1.Get(3)}");  // 期望: C
        Console.WriteLine($"Get(4): {map1.Get(4)}");  // 期望: null (default)

        // 测试SetAll操作
        map1.SetAll("ALL");
        Console.WriteLine("\nSetAll('ALL')后:");
        Console.WriteLine($"Get(1): {map1.Get(1)}");  // 期望: ALL
        Console.WriteLine($"Get(2): {map1.Get(2)}");  // 期望: ALL
        Console.WriteLine($"Get(3): {map1.Get(3)}");  // 期望: ALL
        Console.WriteLine($"Get(4): {map1.Get(4)}");  // 期望: null

        // SetAll后再Put
        map1.Put(2, "NEW_B");
        map1.Put(4, "D");
        Console.WriteLine("\nSetAll后再Put(2,'NEW_B'), Put(4,'D'):");
        Console.WriteLine($"Get(1): {map1.Get(1)}");  // 期望: ALL
        Console.WriteLine($"Get(2): {map1.Get(2)}");  // 期望: NEW_B
        Console.WriteLine($"Get(3): {map1.Get(3)}");  // 期望: ALL
        Console.WriteLine($"Get(4): {map1.Get(4)}");  // 期望: D

        // 再次SetAll
        map1.SetAll("NEW_ALL");
        Console.WriteLine("\n再次SetAll('NEW_ALL'):");
        Console.WriteLine($"Get(1): {map1.Get(1)}");  // 期望: NEW_ALL
        Console.WriteLine($"Get(2): {map1.Get(2)}");  // 期望: NEW_ALL
        Console.WriteLine($"Get(3): {map1.Get(3)}");  // 期望: NEW_ALL
        Console.WriteLine($"Get(4): {map1.Get(4)}");  // 期望: NEW_ALL

        // 测试用例2：数值类型测试
        var map2 = new MyHashMap<string, int>();
        map2.Put("A", 1);
        map2.Put("B", 2);
        map2.SetAll(100);
        map2.Put("C", 3);

        Console.WriteLine("\n测试2 - 数值类型:");
        Console.WriteLine($"Put('A',1), Put('B',2), SetAll(100), Put('C',3)");
        Console.WriteLine($"Get('A'): {map2.Get("A")}");  // 期望: 100
        Console.WriteLine($"Get('B'): {map2.Get("B")}");  // 期望: 100
        Console.WriteLine($"Get('C'): {map2.Get("C")}");  // 期望: 3
        Console.WriteLine($"Get('D'): {map2.Get("D")}");  // 期望: 0 (default)

        // 测试用例3：复杂时序测试
        var map3 = new MyHashMap<int, int>();
        map3.Put(1, 10);
        map3.Put(2, 20);
        map3.SetAll(999);
        map3.Put(3, 30);
        map3.Put(1, 15);  // 重新设置已存在的key
        map3.SetAll(888);
        map3.Put(4, 40);

        Console.WriteLine("\n测试3 - 复杂时序:");
        Console.WriteLine($"Put(1,10), Put(2,20), SetAll(999), Put(3,30), Put(1,15), SetAll(888), Put(4,40)");
        Console.WriteLine($"Get(1): {map3.Get(1)}");  // 期望: 888
        Console.WriteLine($"Get(2): {map3.Get(2)}");  // 期望: 888
        Console.WriteLine($"Get(3): {map3.Get(3)}");  // 期望: 888
        Console.WriteLine($"Get(4): {map3.Get(4)}");  // 期望: 40

        Console.WriteLine("\nSetAll算法测试完成!");
    }
}